﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using PsychSurvey.ResearchId;
using System.ServiceModel.Activation;
using PsychSurvey.Properties;
using PsychSurvey.Resources;
using System.IO;
using System.Web;
using PsychSurvey.Classes;
using System.Web.Hosting;

namespace PsychSurvey
{
    // NOTE: If you change the class name "AdminServiceWCF" here, you must also update the reference to "AdminServiceWCF" in Web.config.
    public class AdminServiceWCF : IAdminServiceWCF
    {
         
        List<Survey> IAdminServiceWCF.GetSurveyList()
        {
            dbDataContext db = new dbDataContext();
            var Results = db.Surveys.Select(x => x);
            return Results.ToList();
        }        
        List<Study> IAdminServiceWCF.GetStudyList()
        {
            dbDataContext db = new dbDataContext();
            var Results = db.Studies.Select(x => x);
            return Results.ToList();
        }
        public Study CreateStudy(out List<Condition> Conditions, out List<StudyWave> Waves)
        {
            Conditions = new List<Condition>();
            Waves = new List<StudyWave>();
            dbDataContext db = new dbDataContext();
            Study s = new Study();
            s.StudyId = Guid.NewGuid();
            s.StudyName = "New Study";
            db.Studies.InsertOnSubmit(s);
            Condition c = new Condition();
            c.ConditionName = "Control Condition";
            s.Conditions.Insert(0,c);
            StudyWave sw = new StudyWave();
            sw.isUserNotifiedbyEmail = false;
            sw.StudyWaveName = "Wave 1";
            sw.DisplayOrder = 0;
            s.StudyWaves.Insert(0, sw);
            db.SubmitChanges();
            Conditions.Add(c);
            Waves.Add(sw);
            return s;
        }

        public StudyWaveSurvey CreateStudyWaveSurvey(StudyWaveSurvey sws)
        {
            //This was enhanced to fix a bug where this gets
            //called when associating a survey and the sws record
            //already exists, so I made it not error when it already
            //exists.
            bool Insert = false;
            dbDataContext db = new dbDataContext();
            StudyWaveSurvey sws_new = (from x in db.StudyWaveSurveys
                                       where x.StudyWaveId == sws.StudyWaveId
                                       && x.SurveyId == sws.SurveyId
                                       && x.Conditionid == sws.Conditionid
                                       select x).FirstOrDefault();
            if (sws_new == null)
            {
                Insert = true;
                sws_new = new StudyWaveSurvey();
                sws_new.Conditionid = sws.Conditionid;
                sws_new.SurveyId = sws.SurveyId;
                sws_new.StudyWaveId = sws.StudyWaveId;
            }            
            sws_new.DisplayOrder = sws.DisplayOrder;            
            if (Insert)
            {
                db.StudyWaveSurveys.InsertOnSubmit(sws_new);
            }
            db.SubmitChanges();
            return sws_new;
        }
         


        public List<Condition> GetConditions(Guid StudyId)
        {
            dbDataContext db = new dbDataContext();
            Study MyStudy = db.Studies.Single(x => x.StudyId == StudyId);
            return MyStudy.Conditions.ToList();
        }

         

         


        public List<StudyWave> GetStudyWaves(Guid StudyId)
        {
            dbDataContext db = new dbDataContext();
            var Waves = from x in db.StudyWaves
                        where x.StudyId == StudyId
                        orderby x.DayStartOffset
                        select x;
            return Waves.ToList();
        }
        public List<StudyWave> GetStudyWavesForConditionId(int ConditionId)
        {
            dbDataContext db = new dbDataContext();
            Guid StudyId = (from y in db.Conditions
                               where y.ConditionId == ConditionId
                               select y.StudyId).Single();
            var Waves = from x in db.StudyWaves
                        where x.StudyId == StudyId
                        orderby x.DayStartOffset
                        select x;
            return Waves.ToList();
        }
         

         


        public List<Survey> GetSurveys(int StudyWaveId, int ConditionId)
        {
            dbDataContext db = new dbDataContext();            
            var surveys = from s in db.Surveys
                          join sws in db.StudyWaveSurveys
                          on s.SurveyId equals sws.SurveyId
                          where sws.StudyWaveId == StudyWaveId
                          & sws.Conditionid == ConditionId
                          orderby sws.DisplayOrder
                          select s;
            return surveys.ToList();
        }
        public List<Survey> GetAllSurveys()
        {
            using (dbDataContext db = new dbDataContext())
            {
                return (from s in db.Surveys
                        orderby s.SurveyName
                        select s).ToList();
            }
        }
        public List<SurveyPage> GetSurveyPages(Guid SurveyId)
        {
            dbDataContext db = new dbDataContext();
            var Pages = from p in db.SurveyPages
                        join sp in db.SurveySurveyPages
                        on p.SurveyPageId equals sp.SurveyPageId
                        where sp.SurveyId == SurveyId
                        orderby sp.DisplayOrder
                        select p;
            List<SurveyPage> PageList = Pages.ToList();
            return PageList;
        }
        public bool DeleteSurveySurveyPages(Guid SurveyId)
        {
            dbDataContext db = new dbDataContext();            
            var ssps = from x in db.SurveySurveyPages
                       where x.SurveyId == SurveyId
                       select x;
            foreach (SurveySurveyPage ssp in ssps.ToList())
            {
                db.SurveySurveyPages.DeleteOnSubmit(ssp);
            }                        
            db.SubmitChanges();
            return true;
        }

        public Study GetStudy(Guid StudyId)
        {
            dbDataContext db = new dbDataContext();
            Study myStudy = db.Studies.Single(x => x.StudyId == StudyId);
            return myStudy;
        }

        public Condition GetCondition(int ConditionId)
        {
            dbDataContext db = new dbDataContext();
            Condition myCondition = db.Conditions.Single(x => x.ConditionId == ConditionId);
            return myCondition;
        }

        public StudyWave GetStudyWave(int StudyWave)
        {
            dbDataContext db = new dbDataContext();
            StudyWave myWave = db.StudyWaves.Single(x => x.StudyWaveId == StudyWave);
            return myWave;
        }

        public Survey GetSurvey(Guid SurveyId)
        {
            dbDataContext db = new dbDataContext();
            Survey mySurvey = db.Surveys.Single(x => x.SurveyId == SurveyId);
            return mySurvey;
        }

        public SurveyPage GetSurveyPage(int SurveyPageId)
        {
            dbDataContext db = new dbDataContext();
            SurveyPage myPage = db.SurveyPages.Single(x => x.SurveyPageId == SurveyPageId);
            return myPage;
        }

         

         


        public bool UpdateSurveyPage(SurveyPage page)
        {
            dbDataContext db = new dbDataContext();
            SurveyPage sp = db.SurveyPages.Single(x => x.SurveyPageId == page.SurveyPageId);
            sp.PageContent = HttpUtility.HtmlDecode(page.PageContent);
            sp.PageName = page.PageName;
            db.SubmitChanges();
            return true;
        }
        public List<SurveySurveyPage> UpdateSurveyPages(List<SurveyPage> pages, Guid SurveyId)
        {
            dbDataContext db = new dbDataContext();
            List<SurveySurveyPage> ssp_old = (from x in db.SurveySurveyPages
                                              where x.SurveyId == SurveyId
                                              select x).ToList();
            db.SurveySurveyPages.DeleteAllOnSubmit(ssp_old);
            db.SubmitChanges();
            int DisplayOrder = 0;
            List<SurveySurveyPage> ssplistnew = new List<SurveySurveyPage>() ;
            foreach (SurveyPage page in pages)
            {
                SurveySurveyPage ssp_new = new SurveySurveyPage();
                ssp_new.SurveyId = SurveyId;
                ssp_new.SurveyPageId = page.SurveyPageId;
                ssp_new.DisplayOrder = DisplayOrder;
                DisplayOrder++;
                db.SurveySurveyPages.InsertOnSubmit(ssp_new);
                ssplistnew.Add(ssp_new);
            }
            db.SubmitChanges();
            return ssplistnew;
        }
        public bool CreateSurveySurveyPage(SurveySurveyPage ssp)
        {
            dbDataContext db = new dbDataContext();
            //Look for existing ssp
            SurveySurveyPage ssp_new = (from x in db.SurveySurveyPages
                                        where x.SurveyId == ssp.SurveyId
                                        && x.SurveyPageId == ssp.SurveyPageId
                                        select x).FirstOrDefault();
            if (ssp_new == null)
            {
                db.SurveySurveyPages.InsertOnSubmit(ssp);
                db.SubmitChanges();
            }            
            return true;
        }
         
        private SurveyPage CreateSurveyPageInternal(Guid SurveyId)
        {
            dbDataContext db = new dbDataContext();
            int Count = db.SurveySurveyPages.Count(x => x.SurveyId == SurveyId);
            SurveyPage page = new SurveyPage();
            page.PageName = "Page " + (Count + 1).ToString();
            page.PageContent = StaticResources.DefaultSurveyPageContent;
            return page;
        }
        public SurveyPage CreateSurveyPage(Guid SurveyId, out SurveySurveyPage ssp)
        {
            dbDataContext db = new dbDataContext();
            SurveyPage sp = CreateSurveyPageInternal(SurveyId);
            db.SurveyPages.InsertOnSubmit(sp);
            ssp = new SurveySurveyPage();
            ssp.SurveyPage = sp;
            ssp.SurveyId = SurveyId;
            ssp.DisplayOrder = db.SurveySurveyPages.Count(x => x.SurveyId == SurveyId);
            db.SurveySurveyPages.InsertOnSubmit(ssp);
            db.SubmitChanges();
            return sp;
        }

        public bool DeleteSurveyPage(SurveyPage page)
        {
            dbDataContext db = new dbDataContext();
            var ssps = from x in db.SurveySurveyPages
                       where x.SurveyPageId == page.SurveyPageId
                       select x;
            foreach (SurveySurveyPage ssp in ssps.ToList())
            {
                db.SurveySurveyPages.DeleteOnSubmit(ssp);
            }
            SurveyPage sp = db.SurveyPages.Single(x => x.SurveyPageId == page.SurveyPageId);
            //The survey page results
            foreach (SurveyPageCompleted spc in sp.SurveyPageCompleteds)
            {
                db.SurveyResults.DeleteAllOnSubmit(spc.SurveyResults);
            }
            db.SurveyPageCompleteds.DeleteAllOnSubmit(sp.SurveyPageCompleteds);
            //The actual survey page
            db.SurveyPages.DeleteOnSubmit(sp);
            db.SubmitChanges();
            return true;
        }

         

         


        public bool UpdateDisplayOrder(Guid SurveyId, int SurveyPageId, int DisplayOrder)
        {
            dbDataContext db = new dbDataContext();
            SurveySurveyPage ssp = db.SurveySurveyPages.Single(x => x.SurveyPageId == SurveyPageId & x.SurveyId == SurveyId);
            ssp.DisplayOrder = DisplayOrder;
            db.SubmitChanges();
            return true;
        }

         

         


        public bool UpdateSurvey(Survey mySurvey)
        {
            dbDataContext db = new dbDataContext();
            Survey survey = db.Surveys.Single(x => x.SurveyId == mySurvey.SurveyId);
            survey.SurveyName = mySurvey.SurveyName;
            db.SubmitChanges();
            return true;
        }

        public bool UpdateSurveyDisplayOrder(int StudyWaveId, Guid SurveyId, int DisplayOrder)
        {
            dbDataContext db = new dbDataContext();
            StudyWaveSurvey sws = db.StudyWaveSurveys.Single(x => x.SurveyId == SurveyId & x.StudyWaveId == StudyWaveId);
            sws.DisplayOrder = DisplayOrder;
            db.SubmitChanges();
            return true;
        }

        public bool RemoveSurvey(int StudyWaveId, int ConditionId, Guid SurveyId)
        {
            dbDataContext db = new dbDataContext();
            var sws = from x in db.StudyWaveSurveys
                      where x.SurveyId == SurveyId &&
                      x.Conditionid == ConditionId
                      select x;
            foreach (StudyWaveSurvey sws1 in sws.ToList())
            {
                db.StudyWaveSurveys.DeleteOnSubmit(sws1);
            }
            db.SubmitChanges();
            return true;
        }       

         


        public Survey CreateSurvey(int StudyWaveId,int Conditionid, out StudyWaveSurvey sws)
        {
            dbDataContext db = new dbDataContext();
            Survey NewSurvey = new Survey();
            NewSurvey.SurveyId = Guid.NewGuid();
            int Count = db.StudyWaveSurveys.Count(x => x.StudyWaveId == StudyWaveId);
            NewSurvey.SurveyName = "Survey " + (Count + 1).ToString();
            sws = new StudyWaveSurvey();
            sws.StudyWaveId = StudyWaveId;
            sws.SurveyId = NewSurvey.SurveyId;
            sws.DisplayOrder = Count + 1;
            sws.Conditionid = Conditionid;
            db.Surveys.InsertOnSubmit(NewSurvey);
            db.StudyWaveSurveys.InsertOnSubmit(sws);
            db.SubmitChanges();
            return NewSurvey;
        }

        public StudyWaveSurvey AssociateExistingSurvey(int StudyWaveId, int ConditionId, Guid SurveyId)
        {
            dbDataContext db = new dbDataContext();
            int Count = db.StudyWaveSurveys.Count(x => x.StudyWaveId == StudyWaveId);
            StudyWaveSurvey sws = new StudyWaveSurvey();
            sws.StudyWaveId = StudyWaveId;
            sws.SurveyId = SurveyId;
            sws.Conditionid = ConditionId;
            sws.DisplayOrder = Count + 1;
            db.StudyWaveSurveys.InsertOnSubmit(sws);
            db.SubmitChanges();
            return sws;
        }

         

        public bool UpdateStudyWave(StudyWave myStudyWave)
        {
            dbDataContext db = new dbDataContext();
            StudyWave sw = db.StudyWaves.Single(x => x.StudyWaveId == myStudyWave.StudyWaveId);
            sw.StudyWaveName = myStudyWave.StudyWaveName;
            sw.DayStartOffset = myStudyWave.DayStartOffset;
            sw.DayEndOffset = myStudyWave.DayEndOffset;
            sw.DisplayOrder = myStudyWave.DisplayOrder;
            sw.isUserNotifiedbyEmail = myStudyWave.isUserNotifiedbyEmail;
            sw.VariableNamePrefix = myStudyWave.VariableNamePrefix;
            db.SubmitChanges();
            return true;
        }
        public bool UpdateStudyWaveSurvey(StudyWaveSurvey mySws)
        {
            dbDataContext db = new dbDataContext();
            StudyWaveSurvey sws = db.StudyWaveSurveys.Single(x => x.StudyWaveId == mySws.StudyWaveId && x.Conditionid == mySws.Conditionid && x.SurveyId == mySws.SurveyId);
            sws.DisplayOrder = mySws.DisplayOrder;
            db.SubmitChanges();
            return true;
        }
        public Condition CreateCondition(Guid StudyId)
        {
            dbDataContext db = new dbDataContext();
            Condition myCondition = new Condition();
            int Count = db.Conditions.Count(x => x.StudyId == StudyId);
            myCondition.ConditionName = "Condition " + (Count + 1).ToString();
            myCondition.StudyId = StudyId;
            db.Conditions.InsertOnSubmit(myCondition);
            db.SubmitChanges();
            return myCondition;
        }

        public bool DeleteCondition(int ConditionId)
        {
            dbDataContext db = new dbDataContext();
            Condition myCondition = db.Conditions.Single(x => x.ConditionId == ConditionId);
            //Delete the individuals in the condition
            db.IndividualConditions.DeleteAllOnSubmit(myCondition.IndividualConditions);
            //Delete the studywavesurvey records
            db.StudyWaveSurveys.DeleteAllOnSubmit(myCondition.StudyWaveSurveys);
            //Delete the completed data associated with this row
            //Delete study data 2
            List<SurveyResult> CompletedResults = (from y in db.SurveyResults
                                                   where y.SurveyPageCompleted.ConditionId == ConditionId
                                                   select y).ToList();
            db.SurveyResults.DeleteAllOnSubmit(CompletedResults);
            //Delete the study data
            List<SurveyPageCompleted> Completed = (from y in db.SurveyPageCompleteds
                                                   where y.ConditionId == ConditionId
                                                   select y).ToList();
            db.SurveyPageCompleteds.DeleteAllOnSubmit(Completed);  
            //Delete the main condition row            
            db.Conditions.DeleteOnSubmit(myCondition);
            db.SubmitChanges();
            return true;
        }

        public bool UpdateCondition(Condition ConditionToSave)
        {
            dbDataContext db = new dbDataContext();
            Condition myCondition = db.Conditions.Single(x => x.ConditionId == ConditionToSave.ConditionId);
            myCondition.ConditionName = ConditionToSave.ConditionName;
            db.SubmitChanges();
            return true;
        }

        public StudyWave CreateWave(Guid StudyId)
        {
            dbDataContext db = new dbDataContext();
            StudyWave sw = new StudyWave();
            sw.StudyId = StudyId;
            int Count = db.StudyWaves.Count(x => x.StudyId == StudyId);
            sw.StudyWaveName = "Study Wave " + (Count + 1).ToString();
            sw.DisplayOrder = Count;
            StudyWave last = (from m in db.StudyWaves
                              where m.StudyId == StudyId   
                              orderby m.DayStartOffset descending
                              select m).FirstOrDefault();
            if (last != null)
            {
                sw.DayStartOffset = last.DayEndOffset + 1;
                sw.DayEndOffset = sw.DayStartOffset + (last.DayEndOffset - last.DayStartOffset);
            }
            else
            {
                sw.DayStartOffset = 0;
                sw.DayEndOffset = 10;
            }
            sw.isUserNotifiedbyEmail = false;
            db.StudyWaves.InsertOnSubmit(sw);
            db.SubmitChanges();
            return sw;
        }

        public bool DeleteStudyWave(int StudyWaveId)
        {
            dbDataContext db = new dbDataContext();
            StudyWave sw = db.StudyWaves.Single(x => x.StudyWaveId == StudyWaveId);
            db.StudyWaves.DeleteOnSubmit(sw);
            db.SubmitChanges();
            return true;
        }
        public bool DeleteStudyWaveSurvey(int StudyWaveId, int ConditionId)
        {
            dbDataContext db = new dbDataContext();
            var swslist = from x in db.StudyWaveSurveys
                       where x.Conditionid == ConditionId
                       && x.StudyWaveId == StudyWaveId
                       select x;
            foreach (StudyWaveSurvey sws in swslist.ToList())
            {
                db.StudyWaveSurveys.DeleteOnSubmit(sws);
            }
            db.SubmitChanges();
            return true;
        }
        public bool UpdateStudy(Study StudyToUpdate)
        {
            dbDataContext db = new dbDataContext();
            Study myStudy = db.Studies.Single(x => x.StudyId == StudyToUpdate.StudyId);
            myStudy.StudyName = StudyToUpdate.StudyName;
            myStudy.OpenDate = StudyToUpdate.OpenDate;
            myStudy.MaxParticipants = StudyToUpdate.MaxParticipants;
            myStudy.StudyDescription = StudyToUpdate.StudyDescription;            
            db.SubmitChanges();
            return true;
        }

        public bool DeleteStudy(Guid StudyId)
        {
            dbDataContext db = new dbDataContext();            
            Study myStudy = db.Studies.Single(x => x.StudyId == StudyId);
            //Delete the study results &&            
            //Delete the IndividualCondition records
            DeleteResults(StudyId);
            List<StudyWave> Waves = myStudy.StudyWaves.ToList();
            List<Condition> Conditions = myStudy.Conditions.ToList();
            //Disassociate the surveys
            List<StudyWaveSurvey> StudyWaveSurveys = (from y in db.StudyWaveSurveys
                                                     where y.Condition.StudyId == StudyId
                                                     select y).ToList();                
            db.StudyWaveSurveys.DeleteAllOnSubmit(StudyWaveSurveys);
            //Delete the conditions
            db.Conditions.DeleteAllOnSubmit(Conditions);
            //Delete the waves
            db.StudyWaves.DeleteAllOnSubmit(Waves);
            //Delete the study            
            db.Studies.DeleteOnSubmit(myStudy);
            //Delete the study notification data
            List<StudyNotification> StudyNotifications = (from x in db.StudyNotifications
                                                          where x.StudyId == StudyId
                                                          select x).ToList();
            db.StudyNotifications.DeleteAllOnSubmit(StudyNotifications);
            //Delete study data 2
            List<SurveyResult> CompletedResults = (from y in db.SurveyResults
                                                          where y.SurveyPageCompleted.StudyId == StudyId
                                                          select y).ToList();
            db.SurveyResults.DeleteAllOnSubmit(CompletedResults);
            //Delete the study data
            List<SurveyPageCompleted> Completed = (from y in db.SurveyPageCompleteds
                                                   where y.StudyId == StudyId
                                                   select y).ToList();
            db.SurveyPageCompleteds.DeleteAllOnSubmit(Completed);  
            //Delete the study claims
            db.StudyClaims.DeleteAllOnSubmit(myStudy.StudyClaims);
            //Delete the session
            db.Sessions.DeleteAllOnSubmit(myStudy.Sessions);
            db.SubmitChanges();
            return true;
        }
        
        private void DeleteStudy(Study StudyToDelete)
        {

        }
        //Study IAdminServiceWCF.CreateStudy()
        //{
        //    return CreateStudy();
        //}
        public string GetStudyUrl(Guid Study)
        {            
#if (DEBUG)
            return PsychSurvey.Properties.Settings.Default.ApplicationRoot_local
               + PsychSurvey.Properties.Settings.Default.StudyPageUrl + "?"
               + Participant.Study.StudyQueryString + "=" + Study.ToString();
#else
             return PsychSurvey.Properties.Settings.Default.ApplicationRoot
               + PsychSurvey.Properties.Settings.Default.StudyPageUrl + "?"
               + Participant.Study.StudyQueryString + "=" + Study.ToString();
#endif
        }

        public string GetStudyDevelopmentUrl(Guid Study)
        {
            #if (DEBUG)
             return PsychSurvey.Properties.Settings.Default.ApplicationRoot_local
               + PsychSurvey.Properties.Settings.Default.StudyPageUrl + "?"
               + Participant.Study.StudyQueryString + "=" + Study.ToString() + "&"
               + Participant.Study.DevelopmentQueryString + "=true";
#else
             return PsychSurvey.Properties.Settings.Default.ApplicationRoot
               + PsychSurvey.Properties.Settings.Default.StudyPageUrl + "?"
               + Participant.Study.StudyQueryString + "=" + Study.ToString() + "&"
               + Participant.Study.DevelopmentQueryString + "=true";
#endif

        }



         
               
        public List<Claim> GetClaimsNotAdded(Guid StudyId)
        {
            return Study.GetClaimsNotAdded(StudyId);
        }
        public List<Claim> GetClaims()
        {
            return Claim.GetClaims();
        }
        public List<Claim> GetClaimsAdded(Guid StudyId)
        {
            return Study.GetClaimsAdded(StudyId);
        }
        public List<StudyClaim> GetStudyClaimAdded(Guid StudyId)
        {
            dbDataContext db = new dbDataContext();
            return Study.GetStudyClaimAdded(StudyId, out db);
        }

        public bool UpdateClaims(Guid StudyId, int[] AllClaims, int[] AnonymousClaims)
        {
            dbDataContext db = new dbDataContext();
            List<StudyClaim> AddedClaims = PsychSurvey.Study.GetStudyClaimAdded(StudyId,out db);
            foreach (StudyClaim myClaim in AddedClaims)
            {
                db.StudyClaims.DeleteOnSubmit(myClaim);
            }
            db.SubmitChanges();
            foreach (int ClaimId in AllClaims)
            {
                StudyClaim sc = new StudyClaim();
                sc.StudyId = StudyId;
                sc.ClaimId = ClaimId;
                if (AnonymousClaims.Contains(ClaimId))
                    sc.IsAnonymous = true;
                db.StudyClaims.InsertOnSubmit(sc);
            }
            db.SubmitChanges();
            return true;
        }
        public void ResumeStudy(int IndividualId, Guid StudyId
            , bool IsTesting
            , out Study myStudy, out Condition myCondition
            , out List<StudyConsolidatedOrderedIndividualResult> SurveyPages
            , out DateTime? NextWaveStartDate
            , out DateTime? NextWaveEndDate
            )
        {
            // Check to see if the individual is in the study
            // Join study if not joined already
            myStudy = Study.GetStudy(StudyId);
            if (myStudy.IsIndividualJoined(IndividualId) == false)
            {
                myStudy.AddIndividualToStudy(IndividualId, IsTesting);
            }
            IndividualCondition myIc = myStudy.GetConditionForIndividual(IndividualId);
            myCondition = myIc.Condition;
            // Get the current wave
            StudyWave myWave = myStudy.GetNextStudyWave(IndividualId);
            // No waves to complete at this time
            if (myWave != null)
            {
                // Now I have a wave, so I get the actual surveys to complete
                SurveyPages = myStudy.GetIncompleteStudyPages(IndividualId, myWave.StudyWaveId);
            }
            else
            {
                // No wave, so nothing to return
                SurveyPages = new List<StudyConsolidatedOrderedIndividualResult>();
            }
            // Get future wave dates
            myStudy.GetFutureStudyWaveAppointment(IndividualId, out NextWaveStartDate, out NextWaveEndDate);
            return;
        }

         



         


        public void BeginSession(int IndividualId, Guid StudyId, bool IsTesting)
        {
            Study myStudy = Study.GetStudy(StudyId);
            myStudy.OpenSession(IndividualId);
            if (!myStudy.IsIndividualJoined(IndividualId))
            {
                myStudy.AddIndividualToStudy(IndividualId, IsTesting);
            }            
        }

        public void EndSession(int IndividualId, Guid StudyId)
        {
            Study.GetStudy(StudyId).CloseSession(IndividualId);
        }

         

         


        public StudyConsolidatedOrderedResults GetNextSurveyPage(Guid StudyId, int IndividualId)
        { 
            //Study myStudy = Study.GetStudy(StudyId);
            
            //return
            //    (from x in myStudy.GetStudyPagesWithResults(IndividualId)
            //     where x.PageContentModified == null
            //     select x).FirstOrDefault();
            return new StudyConsolidatedOrderedResults();
        }

         

         


        public void ReportSurveyPageResults(Guid StudyId, int IndividualId, int StudyWaveId,
            Guid SurveyId, int SurveyPageId, string[] Names, string[] Values)
        {
            Study myStudy = Study.GetStudy(StudyId);
            IndividualCondition myCondition = myStudy.GetConditionForIndividual(IndividualId);            
            Study.ReportSurveyPageResults(IndividualId
                , SurveyPageId, SurveyId
                , StudyWaveId, myCondition.ConditionId
                ,StudyId, "", Names, Values);            
        }

        public void DeleteResults(Guid StudyId)
        {
            dbDataContext db = new dbDataContext();
            foreach (SurveyPageCompleted sp in (from x in db.SurveyPageCompleteds
                                                where x.StudyId == StudyId
                                                select x))
            {
                foreach (SurveyResult sr in sp.SurveyResults)
                {
                    db.SurveyResults.DeleteOnSubmit(sr);
                }
                db.SurveyPageCompleteds.DeleteOnSubmit(sp);
            }
            foreach (IndividualCondition ic in from x in db.IndividualConditions
                                               where x.StudyId == StudyId
                                               select x)
            {
                db.IndividualConditions.DeleteOnSubmit(ic);
            }
            db.SubmitChanges();
        }

         

         


        public void CountParticipants(Guid StudyId, out int TotalParticipants, out List<ConditionCount> ConditionCount)
        {
            TotalParticipants = Study.GetParticipantCount(StudyId);
            ConditionCount = Study.GetConditionCount(StudyId);
        }

         

         


        public StudyConsolidatedOrderedResults GetPreviousSurveyPage(Guid StudyId, int IndividualId, int StudyWaveId, Guid SurveyId, int SurveyPageId)
        {
            return new StudyConsolidatedOrderedResults();            
        }

        public StudyConsolidatedOrderedResults GetNextSurveyPage2(Guid StudyId, int IndividualId, int StudyWaveId, Guid SurveyId, int SurveyPageId)
        {
            return new StudyConsolidatedOrderedResults();
        }

        public void GetSurveyData(out List<Study> Studies,             
            out List<Condition> Conditions,             
            out List<StudyWave> Waves,
            out List<StudyWaveSurvey> StudyWaveSurveys,
            out List<Survey> Surveys,
            out List<SurveySurveyPage> SurveySurveyPages,
            out List<SurveyPage> Pages,
            out List<StudyClaim> StudyClaims            
            )
        {
            Studies = PsychSurvey.Study.GetStudyList();
            Guid[] StudyIds = Studies.Select(x => x.StudyId).ToArray();
            Conditions = PsychSurvey.Condition.GetConditions(StudyIds);
            Waves = PsychSurvey.StudyWave.GetStudyWaves(StudyIds);
            StudyWaveSurveys = PsychSurvey.StudyWaveSurvey.GetStudyWaveSurvey(StudyIds);
            Surveys = PsychSurvey.Survey.GetSurvey(StudyIds);
            Guid[] SurveyIds = Surveys.Select(x => x.SurveyId).ToArray();
            SurveySurveyPages = PsychSurvey.SurveySurveyPage.GetSurveySurveyPage(SurveyIds);
            Pages = PsychSurvey.SurveyPage.GetSurveyPage(SurveyIds);
            StudyClaims = Study.GetStudyClaims(StudyIds);
        }

        public bool LoginUser(string Username, string Password, out int UserId)
        {
            UserAuthenticate u = new UserAuthenticate(true);
            int i;
            bool Result = u.LoginUser(Username, Password, out i);
            
            // Give the PPID and the UserName
            Individual LocalIndividual = Individual.CreateIndividualIfNotExists(Username, i);
            // This is the actual local IndividualId
            UserId = LocalIndividual.IndividualId;
            return Result;
        }
        public IndividualClaimsView[] GetClaimsForIndividual(string LoginName, int[] ClaimId)
        {
            UserAuthenticate u = new UserAuthenticate(true);
            IndividualClaimsView[] claims = u.GetClaims(LoginName, ClaimId);
            //Update Claims in the Psych database
            foreach (IndividualClaimsView claim in claims)
            {
                IndividualClaim.CreateIndividualClaim(claim.IndividualId
                    , (ClaimEnum)claim.ClaimId, claim.Value, "");
            }
            return claims;
        }
        public bool CreateAccount(string Username, string Password)
        {
            UserAuthenticate u = new UserAuthenticate(true);
            return u.CreateAccount(Username, Password);
        }
        public void CreateClaim(string UserName, int ClaimId, string Value)
        {
            UserAuthenticate u = new UserAuthenticate(true);
            u.AddClaim(UserName, ClaimId, Value);
        }
        public bool ValidateUserClaims(Guid StudyId, string LoginName, int UserId, out List<string> MissingClaimNames )
        {
            //First we lookup the user by our ID
            UserAuthenticate u = new UserAuthenticate(true);            
            //Next we get the required claims for the study
            List<Claim> RequiredClaims = Study.GetClaimsAdded(StudyId);
            IndividualClaimsView[] ActualClaims = u.GetClaims(LoginName
                , (from y in RequiredClaims select y.ClaimId).ToArray());
            List<int> ActualClaimIds = (from y in ActualClaims select y.ClaimId).ToList();
            MissingClaimNames = new List<string>();
            foreach (Claim RequiredClaim in RequiredClaims)
            {
                if (ActualClaimIds.Contains(RequiredClaim.ClaimId) == false)
                {
                    MissingClaimNames.Add(RequiredClaim.ClaimName);
                }
            }
            if (MissingClaimNames.Count > 0)
                return false;
            //If we're still here, they have everything, so we save the claims
            foreach (IndividualClaimsView ActualClaim in ActualClaims)
            {
                IndividualClaim.CreateIndividualClaim(UserId, (ClaimEnum)ActualClaim.ClaimId, ActualClaim.Value, "");
            }
            return true;
        }
        public List<StudyResultsIndividualEmail> GetStudyResults(Guid StudyId)
        {
            return Study.GetStudyResults(StudyId);
        }
        public void DeleteStudyResults(Guid StudyId, int IndividualId)
        {
            Study.DeleteIndividualFromStudy(StudyId, IndividualId);
        }
        public void UpdateClaimsForStudy(Guid StudyId, List<Claim> ClaimsAdded)
        {
            Study.UpdateClaims(StudyId, ClaimsAdded);
        }
        public List<string> GetResourcesForStudyId(Guid StudyId)
        {
            StudyFileHandler Handler = new StudyFileHandler(HostingEnvironment.ApplicationPhysicalPath, StudyId.ToString());
            return Handler.GetContentsForStudy();
        }
        public void DeleteResource(string Path, Guid StudyId)
        {
            StudyFileHandler Handler = new StudyFileHandler(HostingEnvironment.ApplicationPhysicalPath, StudyId.ToString());
            Handler.DeleteFile(Path);
        }
    }
    public class MyServiceHostFactory : ServiceHostFactory
    {
        protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
        {
            // Specify the exact URL of your web service

            Uri webServiceAddress = null;
            #if (DEBUG)
            webServiceAddress = new Uri(Settings.Default.AdminServiceUrl_local);
            #else
            webServiceAddress = new Uri(Settings.Default.AdminServiceUrl);
#endif

            MyServiceHost webServiceHost = new MyServiceHost(serviceType, webServiceAddress);
            return webServiceHost;
        }
    }

    public class MyServiceHost : ServiceHost
    {
        public MyServiceHost(Type serviceType, params Uri[] baseAddresses)
            : base(serviceType, baseAddresses)
        { }

        protected override void ApplyConfiguration()
        {
            base.ApplyConfiguration();
        }
    }
}
